package com.ruoyi.system.service.impl;

import java.util.Date;
import java.util.List;

import com.ruoyi.system.domain.UserCoupon;
import com.ruoyi.system.mapper.UserCouponMapper;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.CouponMapper;
import com.ruoyi.system.domain.Coupon;
import com.ruoyi.system.service.CouponService;

/**
 * 优惠券信息Service业务层处理
 * 
 * @author adf
 * @date 2024-09-10
 */
@Service("couponService")
public class CouponServiceImpl implements CouponService
{
    @Autowired
    private CouponMapper couponMapper;

    @Autowired
    private UserCouponMapper userCouponMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 查询优惠券信息
     * 
     * @param id 优惠券信息主键
     * @return 优惠券信息
     */
    @Override
    public Coupon selectCouponById(Long id)
    {
        return couponMapper.selectCouponById(id);
    }

    /**
     * 根据商户id查询优惠券信息列表
     * @param id
     * @return
     */
    public List<Coupon> selectCouponByMidList(Long id)
    {
        Coupon coupon = new Coupon();
        List<Coupon> coupons = couponMapper.selectCouponList(coupon);
        System.out.println("coupons:"+coupons);
        for (Coupon coupon1 : coupons) {
            // 检查商户优惠券是否已过期
            // 跳过新人优惠券
            if(coupon1.getId() == 1){
                continue;
            }
            if(coupon1.getEnd().before(new Date())){
                // 优惠券已过期, 修改状态为已过期
                coupon1.setStatus(1L);
                couponMapper.updateCoupon(coupon1);
            }
        }
        return couponMapper.selectCouponByMidList(id);
    }

    /**
     * 根据用户id查询优惠券信息列表
     * @param uid
     * @return
     */
     public List<Coupon> selectCouponByUidList(Long uid) {
         UserCoupon userCoupon = new UserCoupon();
         List<UserCoupon> userCoupons = userCouponMapper.selectUserCouponList(userCoupon);
         for (UserCoupon coupon : userCoupons) {
             // 检查用户优惠券是否已过期
             if(coupon.getExpirationEnd().before(new Date())){
                 // 优惠券已过期, 修改状态为已过期
                 coupon.setStatus(2L);
                 userCouponMapper.updateUserCoupon(coupon);
             }
         }
         return couponMapper.selectCouponByUidList(uid);
     }

     /**
     * 查询优惠券信息列表
     * 
     * @param coupon 优惠券信息
     * @return 优惠券信息
     */
    @Override
    public List<Coupon> selectCouponList(Coupon coupon)
    {
        return couponMapper.selectCouponList(coupon);
    }

    /**
     * 新增优惠券信息
     * 
     * @param coupon 优惠券信息
     * @return 结果
     */
    @Override
    public int insertCoupon(Coupon coupon)
    {
        //新增优惠券，利用rabbitMQ将消息通知到所有用户
        int i = couponMapper.insertCoupon(coupon);
        // 设置消息确认回调函数
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             *
             * @param correlationData 自定义配置信息 (发送消息时候可以设置)
             * @param ack exchange交换机是否成功收到消息，true 成功，false 失败
             * @param cause 失败原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("确认模式回调函数执行了...：");
                if (ack) {
                    System.out.println("exchange 接收消息成功");
                } else {
                    System.out.println("exchange 接收消息失败：原因：" + cause);
                    //做一些处理，让消息再次发送 【应用问题部分解决】
                }
            }
        });
        /*
        2、设置Exchange处理失败消息的方式:
        false：如果消息没有路由到Queue，将消息丢弃，不会触发回调函数
        true：如果消息没有路由到Queue，返回给消息发送方，执行回调函数
        */
        rabbitTemplate.setMandatory(true);
        /**
         * 1、消息投递到queue失败，回调函数
         */
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            /**
             * @param returnedMessage 返回信息对象
             */
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                System.out.println("退回模式回调函数执行了:");
                System.out.println("失败代码：" + returnedMessage.getReplyCode());
                System.out.println("失败描述：" + returnedMessage.getReplyText());
                System.out.println("消息内容：" + returnedMessage.getMessage());
                System.out.println("交换机：" + returnedMessage.getExchange());
                System.out.println("路由key：" + returnedMessage.getRoutingKey());
                //做一些处理，让消息再次发送 【应用问题部分解决】
                //解决方案：定时检查服务，每隔指定时间，检查 DB 和 MDB 数据是否匹配，如果匹配失败，定时检查服务通过远程调用方式，调用Producer，重新发送消息
                //调用Producer，重新发送消息

            }
        });
//        if (i == 1) {
//            /*
//            * 对整个队列（Queue）设置过期时间：通过队列属性设置，队列中所有消息都有相同的过期时间（推荐）
//            * // 声明队列1：设置消息过期时间为10s
//                @Bean
//                    public Queue ttlQueue1() {
//                    return QueueBuilder.durable("test_ttl_queue_1").ttl(10 * 1000).build();
//                }
//            * 设置消息过期时间
//            * 参数：过期时间，单位毫秒
//             * */
//            rabbitTemplate.convertAndSend("springboot_topic_exchange", "coupons.add", "添加优惠券信息, coupon.add", new MessagePostProcessor() {
//                @Override
//                public Message postProcessMessage(Message message) throws AmqpException
//                {
//                    // 设置message的参数
//                    message.getMessageProperties().setExpiration("10000");
//                    // 返回message对象
//                    return message;
//                }
//            });
//        }
        return i;
    }

    /**
     * 修改优惠券信息
     * 
     * @param coupon 优惠券信息
     * @return 结果
     */
    @Override
    public int updateCoupon(Coupon coupon)
    {
        return couponMapper.updateCoupon(coupon);
    }

    /**
     * 批量删除优惠券信息
     * 
     * @param ids 需要删除的优惠券信息主键
     * @return 结果
     */
    @Override
    public int deleteCouponByIds(Long[] ids)
    {
        return couponMapper.deleteCouponByIds(ids);
    }

    /**
     * 删除优惠券信息信息
     * 
     * @param id 优惠券信息主键
     * @return 结果
     */
    @Override
    public int deleteCouponById(Long id)
    {
        return couponMapper.deleteCouponById(id);
    }
}
